home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / games / IndiZone / sw / universe.c++ < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  12.5 KB  |  452 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include "sw.h"
  18. #include "extern.h"
  19. #include "universe.h"
  20. #include "main.h"
  21. #include "ship.h"
  22. #include "stars.h"
  23. #include "resources.h"
  24. #include <Inventor/nodes/SoGroup.h>
  25. #include <Inventor/nodes/SoRotation.h>
  26. #include <Inventor/nodes/SoDirectionalLight.h>
  27. #include <Inventor/nodes/SoEnvironment.h>
  28. #include <Inventor/nodes/SoComplexity.h>
  29. #include <Inventor/nodes/SoSphere.h>
  30. #include <Inventor/nodes/SoCube.h>
  31. #include <Inventor/nodes/SoMaterial.h>
  32. #include <Inventor/nodes/SoDrawStyle.h>
  33. #include <Inventor/nodes/SoSwitch.h>
  34. #include <gl/gl.h>
  35.  
  36. #define    RADARSIDES    12
  37.  
  38. SoSeparator*        universe;        // universe database
  39. SoPerspectiveCamera*    camera;            // ship's camera
  40. SoTranslation*        position;        // camera position
  41. SoSeparator*        ships;            // ships under here
  42.  
  43. static float        teamBasePos[NUMTEAMS][3] = {
  44.                 { -FIELDSIZE, -FIELDSIZE, FIELDSIZE },
  45.                 { FIELDSIZE, -FIELDSIZE, -FIELDSIZE },
  46.                 { -FIELDSIZE, FIELDSIZE, FIELDSIZE },
  47.                 { FIELDSIZE, FIELDSIZE, -FIELDSIZE } };
  48. static float        baseRadar[RADARSIDES][2];
  49.  
  50. #define    FS        (1.2 * FIELDSIZE)
  51. static float        asteroidPos[MAXASTEROIDS][3] = {
  52.                 { 0.336242*FS, 0.488682*FS, 0.441743*FS},
  53.                 { -0.148313*FS, 0.309765*FS, -0.190327*FS},
  54.                 { 0.759522*FS, 0.369414*FS, -0.994095*FS},
  55.                 { 0.355943*FS, 0.50475*FS, 0.579178*FS},
  56.                 { 0.613972*FS, -0.544913*FS, 0.37368*FS},
  57.                 { -0.582548*FS, -0.533237*FS, 0.770545*FS},
  58.                 { -0.386152*FS, 0.735704*FS, 0.892255*FS},
  59.                 { -0.537149*FS, -0.155228*FS, -0.477868*FS},
  60.                 { -0.439326*FS, -0.762477*FS, 0.487417*FS},
  61.                 { 0.860059*FS, -0.92119*FS, 0.847345*FS},
  62.                 { -0.163824*FS, -0.246843*FS, 0.121367*FS},
  63.                 { -0.566678*FS, 0.200692*FS, 0.0515372*FS},
  64.                 { -0.875666*FS, -0.659752*FS, 0.315128*FS},
  65.                 { -0.13777*FS, 0.657194*FS, 0.558865*FS},
  66.                 { -0.961172*FS, 0.82217*FS, -0.00139434*FS},
  67.                 { -0.656373*FS, -0.570957*FS, 0.412901*FS},
  68.                 { -0.536116*FS, 0.957052*FS, 0.92711*FS},
  69.                 { -0.755732*FS, -0.405562*FS, -0.0520596*FS},
  70.                 { -0.143542*FS, 0.141403*FS, -0.181507*FS},
  71.                 { 0.572489*FS, 0.622042*FS, 0.352845*FS},
  72.                 { -0.0643383*FS, -0.0193419*FS, -0.474457*FS},
  73.                 { -0.742051*FS, -0.272766*FS, -0.469329*FS},
  74.                 { -0.331464*FS, -0.102372*FS, -0.220405*FS},
  75.                 { -0.102167*FS, -0.942594*FS, -0.837588*FS},
  76.                 { 0.0567852*FS, -0.0502296*FS, 0.940972*FS},
  77.                 { 0.625724*FS, -0.889111*FS, 0.211249*FS},
  78.                 { -0.83133*FS, -0.719854*FS, 0.69488*FS},
  79.                 { 0.57322*FS, -0.229432*FS, -0.219259*FS},
  80.                 { 0.858013*FS, -0.290109*FS, 0.544527*FS},
  81.                 { 0.672019*FS, 0.934613*FS, -0.675743*FS},
  82.                 { 0.895152*FS, 0.752686*FS, -0.729632*FS},
  83.                 { 0.977198*FS, -0.569804*FS, -0.0937383*FS},
  84.                 { 0.461306*FS, -0.996515*FS, 0.439359*FS},
  85.                 { 0.0497952*FS, -0.810878*FS, -0.281791*FS},
  86.                 { 0.251234*FS, 0.999152*FS, 0.465801*FS},
  87.                 { 0.0676605*FS, -0.935549*FS, 0.631452*FS} };
  88. #define    BR        BASERADIUS
  89. static float        asteroidRad[MAXASTEROIDS] =
  90.                 { 2.65415*BR,
  91.                   0.271357*BR,
  92.                   1.0589*BR,
  93.                   0.410823*BR,
  94.                   0.915408*BR,
  95.                   1.15367*BR,
  96.                   0.105465*BR,
  97.                   2.18785*BR,
  98.                   1.50325*BR,
  99.                   0.399032*BR,
  100.                   0.271209*BR,
  101.                   0.926577*BR,
  102.                   1.67525*BR,
  103.                   1.32417*BR,
  104.                   0.618128*BR,
  105.                   0.168644*BR,
  106.                   0.809082*BR,
  107.                   0.0168345*BR,
  108.                   2.65415*BR,
  109.                   0.271357*BR,
  110.                   1.0589*BR,
  111.                   0.410823*BR,
  112.                   0.915408*BR,
  113.                   1.15367*BR,
  114.                   0.105465*BR,
  115.                   2.18785*BR,
  116.                   1.50325*BR,
  117.                   0.399032*BR,
  118.                   0.271209*BR,
  119.                   0.926577*BR,
  120.                   1.67525*BR,
  121.                   1.32417*BR,
  122.                   0.618128*BR,
  123.                   0.168644*BR,
  124.                   0.809082*BR,
  125.                   0.0168345*BR };
  126.  
  127. static float*        asteroidMass;
  128. static int        numAsteroids;
  129. static SoSwitch**    asteroidSwitch;
  130. static float        (*asteroidRadar)[RADARSIDES][2];
  131.  
  132. enum            { NotInSpace = 0, InSpace = 1,
  133.               NotVisible = 0, Visible = 2,
  134.               SwitchedOn = InSpace | Visible };
  135.  
  136. static SoSwitch*    flags[NUMTEAMS];
  137. static SoSeparator*    flagGeom[NUMTEAMS];
  138. static SoTranslation*    flagPos[NUMTEAMS];
  139. static SoRotation*    flagRot;
  140. static int        flagState[NUMTEAMS];
  141. static SbRotation    flagSpin(SbVec3f(0.0, 0.0, 1.0),
  142.                     SbVec3f(0.05416, -0.02394, 0.8845));
  143.  
  144. static SoSeparator*    makeTeamBase(Team t)
  145. {
  146.   SoSeparator* base = new SoSeparator;
  147.   base->setGLRenderCaching(TRUE);
  148.  
  149.   SoDrawStyle* baseStyle = new SoDrawStyle;
  150.   base->addChild(baseStyle);
  151.   baseStyle->style = SoDrawStyle::LINES;
  152.  
  153.   SoMaterial* baseMat = new SoMaterial;
  154.   base->addChild(baseMat);
  155.   baseMat->ambientColor.setValue(teamColor(t, 0.3));
  156.   baseMat->diffuseColor.setValue(teamColor(t, 1.0));
  157.  
  158.   SoComplexity* baseCmplx = new SoComplexity;
  159.   base->addChild(baseCmplx);
  160.   baseCmplx->value = 0.33;
  161.  
  162.   SoTranslation* basePos = new SoTranslation;
  163.   base->addChild(basePos);
  164.   basePos->translation.setValue(teamBasePos[t]);
  165.  
  166.   SoSphere* baseGeom = new SoSphere;
  167.   base->addChild(baseGeom);
  168.   baseGeom->radius = BASERADIUS;
  169.  
  170.   return base;
  171. }
  172.  
  173. static void        makeBaseRadar()
  174. {
  175.   for (int i = 0; i < RADARSIDES; i++) {
  176.     baseRadar[i][0] = BASERADIUS * cos(2.0 * M_PI * float(i) / RADARSIDES);
  177.     baseRadar[i][1] = BASERADIUS * sin(2.0 * M_PI * float(i) / RADARSIDES);
  178.   }
  179. }
  180.  
  181. static SoSeparator*    makeAsteroids()
  182. {
  183.   SoSeparator* asteroids = new SoSeparator;
  184.  
  185.   SoMaterial* asteroidMat = new SoMaterial;
  186.   asteroids->addChild(asteroidMat);
  187.   asteroidMat->ambientColor.setValue(0.1, 0.1, 0.1);
  188.   asteroidMat->diffuseColor.setValue(0.5, 0.5, 0.5);
  189.  
  190.   numAsteroids = MAXASTEROIDS;
  191.   asteroidMass = new float[numAsteroids];
  192.   asteroidSwitch = new SoSwitch* [numAsteroids];
  193.   asteroidRadar = (float(*)[RADARSIDES][2])new float[numAsteroids*RADARSIDES*2];
  194.   for (int i = 0; i < numAsteroids; i++) {
  195.     asteroidMass[i] = asteroidRad[i] * asteroidRad[i] * asteroidRad[i];
  196.  
  197.     asteroidSwitch[i] = new SoSwitch;
  198.     asteroids->addChild(asteroidSwitch[i]);
  199.     asteroidSwitch[i]->whichChild = SO_SWITCH_NONE;
  200.  
  201.     // make two levels of complexity for asteroids
  202.     SoSeparator* a = new SoSeparator;
  203.     a->setGLRenderCaching(TRUE);
  204.     asteroidSwitch[i]->addChild(a);
  205.  
  206.     SoComplexity* asteroidCmplx = new SoComplexity;
  207.     a->addChild(asteroidCmplx);
  208.     asteroidCmplx->value = 0.33;
  209.  
  210.     SoTranslation* aPos = new SoTranslation;
  211.     a->addChild(aPos);
  212.     aPos->translation.setValue(asteroidPos[i]);
  213.  
  214.     SoSphere* aGeom = new SoSphere;
  215.     a->addChild(aGeom);
  216.     aGeom->radius = asteroidRad[i];
  217.  
  218.     a = new SoSeparator;
  219.     a->setGLRenderCaching(TRUE);
  220.     asteroidSwitch[i]->addChild(a);
  221.  
  222.     asteroidCmplx = new SoComplexity;
  223.     a->addChild(asteroidCmplx);
  224.     asteroidCmplx->value = 0.1;
  225.  
  226.     a->addChild(aPos);
  227.     a->addChild(aGeom);
  228.  
  229.     for (int j = 0; j < RADARSIDES; j++) {
  230.       asteroidRadar[i][j][0] = asteroidRad[i] *
  231.                 cos(2.0 * M_PI * float(j) / RADARSIDES);
  232.       asteroidRadar[i][j][1] = asteroidRad[i] *
  233.                 sin(2.0 * M_PI * float(j) / RADARSIDES);
  234.     }
  235.   }
  236.  
  237.   return asteroids;
  238. }
  239.  
  240. static SoSwitch*    makeTeamFlag(Team t, SoGroup* flagBasic)
  241. {
  242.   flagState[int(t)] = NotInSpace | NotVisible;
  243.  
  244.   flags[int(t)] = new SoSwitch;
  245.   flags[int(t)]->whichChild = SO_SWITCH_NONE;
  246.   SoSeparator* flagSep = new SoSeparator;
  247.   flags[int(t)]->addChild(flagSep);
  248.   flagSep->addChild(flagPos[int(t)] = new SoTranslation);
  249.  
  250.   flagSep->addChild(flagGeom[int(t)] = new SoSeparator);
  251.   flagGeom[int(t)]->ref();
  252.   SoMaterial* flagMat = new SoMaterial;
  253.   flagGeom[int(t)]->addChild(flagMat);
  254.   flagMat->ambientColor.setValue(teamColor(t, 0.3));
  255.   flagMat->diffuseColor.setValue(teamColor(t, 1.0));
  256.   flagGeom[int(t)]->addChild(flagBasic);
  257.  
  258.   return flags[int(t)];
  259. }
  260.  
  261. SoSeparator*        makeUniverse()
  262. {
  263.   universe = new SoSeparator;
  264.   universe->ref();
  265.  
  266.   // keep camera isolated so hud is not transformed
  267.   SoSeparator* space = new SoSeparator;        // all space under here
  268.   universe->addChild(space);
  269.  
  270.   // add ship's camera for view screen
  271.   space->addChild(camera = new SoPerspectiveCamera);
  272.  
  273.   // add stars
  274.   space->addChild(makeStars(NUMSTARS));
  275.  
  276.   // add some ambient light
  277.   SoEnvironment* ambient = new SoEnvironment;
  278.   space->addChild(ambient);
  279.   ambient->ambientIntensity.setValue(0.4);
  280.  
  281.   // add a light source for the sun
  282.   SoDirectionalLight *sun = new SoDirectionalLight;
  283.   space->addChild(sun);
  284.   sun->direction.setValue(-1.0, 0.0, 0.0);
  285.   sun->color.setValue(1.0, 1.0, 0.75);
  286.   sun->intensity = 1.0;
  287.  
  288.   // make translation to position camera
  289.   space->addChild(position = new SoTranslation);
  290.   position->translation.setValue(0.0, 0.0, 0.0);
  291.  
  292.   // make separator for all ships
  293.   space->addChild(ships = new SoSeparator);
  294.  
  295.   // make team bases
  296.   space->addChild(makeTeamBase(RedTeam));
  297.   space->addChild(makeTeamBase(GreenTeam));
  298.   space->addChild(makeTeamBase(BlueTeam));
  299.   space->addChild(makeTeamBase(PurpleTeam));
  300.   makeBaseRadar();
  301.  
  302.   // make asteroids
  303.   space->addChild(makeAsteroids());
  304.  
  305.   // make flags (which are cubes, naturally)
  306.   SoGroup* flagBasic = new SoGroup;
  307.   flagBasic->ref();
  308.   SoComplexity* flagCmplx = new SoComplexity;
  309.   flagBasic->addChild(flagCmplx);
  310.   flagCmplx->value = 0.0;
  311.   flagBasic->addChild(flagRot = new SoRotation);
  312.   SoCube* flagGeom = new SoCube;
  313.   flagBasic->addChild(flagGeom);
  314.   flagGeom->width = FLAGSIZE;
  315.   flagGeom->height = FLAGSIZE;
  316.   flagGeom->depth = FLAGSIZE;
  317.  
  318.   space->addChild(makeTeamFlag(RedTeam, flagBasic));
  319.   space->addChild(makeTeamFlag(GreenTeam, flagBasic));
  320.   space->addChild(makeTeamFlag(BlueTeam, flagBasic));
  321.   space->addChild(makeTeamFlag(PurpleTeam, flagBasic));
  322.  
  323.   return universe;
  324. }
  325.  
  326. void            deleteUniverse()
  327. {
  328.   for (int i = 0; i < NUMTEAMS; i++)
  329.     flagGeom[i]->unref();
  330.   universe->unref();
  331.   delete[] asteroidMass;
  332. }
  333.  
  334. void            universeAdvance(float /*dt*/)
  335. {
  336.   // spin flags        FIXME -- make depend on dt
  337.   flagRot->rotation.setValue(flagSpin * flagRot->rotation.getValue());
  338.  
  339. }
  340.  
  341. Team            insideBase(float p[3], float r)
  342. {
  343.   float dx, dy, dz;
  344.   for (int i = 0; i < NUMTEAMS; i++) {
  345.     dx = p[0] - teamBasePos[i][0];
  346.     dy = p[1] - teamBasePos[i][1];
  347.     dz = p[2] - teamBasePos[i][2];
  348.     if (dx*dx + dy*dy + dz*dz < BASERADIUS*BASERADIUS + r*r) return Team(i);
  349.   }
  350.   return NoTeam;
  351. }
  352.  
  353. float*            basePosition(Team t)
  354. {
  355.   return teamBasePos[int(t)];
  356. }
  357.  
  358. void            drawRadarBase(Team)
  359. {
  360.   bgnclosedline();
  361.   for (int j = 0; j < RADARSIDES; j++)
  362.     v2f(baseRadar[j]);
  363.   endclosedline();
  364. }
  365.  
  366. int            numberAsteroids()
  367. {
  368.   return numAsteroids;
  369. }
  370.  
  371. float*            asteroidPosition(int n)
  372. {
  373.   return asteroidPos[n];
  374. }
  375.  
  376. float            asteroidRadius(int n)
  377. {
  378.   return asteroidRad[n];
  379. }
  380.  
  381. void            asteroidVisibility(int num, long child)
  382. {
  383.   if (child == -1)
  384.     asteroidSwitch[num]->whichChild = SO_SWITCH_NONE;
  385.   else
  386.     asteroidSwitch[num]->whichChild = child;
  387. }
  388.  
  389. int            hitAsteroid(float p[3], float r)
  390. {
  391.   float dx, dy, dz;
  392.   for (int i = 0; i < numAsteroids; i++) {
  393.     float ar = r + asteroidRad[i];
  394.     dx = p[0] - asteroidPos[i][0];
  395.     if (fabs(dx) > ar) continue;
  396.     dy = p[1] - asteroidPos[i][1];
  397.     if (fabs(dy) > ar) continue;
  398.     dz = p[2] - asteroidPos[i][2];
  399.     if (dx*dx + dy*dy + dz*dz <= ar * ar)
  400.       return i;
  401.   }
  402.   return -1;
  403. }
  404.  
  405. void            gravityAcceleration(float p[3], float a[3])
  406. {
  407.   a[0] = a[1] = a[2] = 0.0;
  408.   float d, dx, dy, dz;
  409.   for (int i = 0; i < numAsteroids; i++) {
  410.     dx = p[0] - asteroidPos[i][0];
  411.     dy = p[1] - asteroidPos[i][1];
  412.     dz = p[2] - asteroidPos[i][2];
  413.     d = sqrt(dx * dx + dy * dy + dz * dz);
  414.     if (d < asteroidRad[i]) continue;    // inside so ignore
  415.     d = 1.0 / d;
  416.     a[0] += asteroidMass[i] * dx * d;
  417.     a[1] += asteroidMass[i] * dy * d;
  418.     a[2] += asteroidMass[i] * dz * d;
  419.   }
  420. }
  421.  
  422. void            drawRadarAsteroid(int num)
  423. {
  424.   bgnclosedline();
  425.   for (int j = 0; j < RADARSIDES; j++)
  426.     v2f(asteroidRadar[num][j]);
  427.   endclosedline();
  428. }
  429.  
  430. SoSeparator*        flagGeometry(Team t)
  431. {
  432.   return flagGeom[int(t)];
  433. }
  434.  
  435. void            flagInSpace(Team t, int e)
  436. {
  437.   if (e) flagState[int(t)] |= InSpace;
  438.   else flagState[int(t)] &= ~InSpace;
  439.   TeamInfo& ti = getTeam(t);
  440.   flagPos[int(t)]->translation.setValue(ti.position);
  441.   flags[int(t)]->whichChild = (flagState[int(t)] == SwitchedOn) ?
  442.                     SO_SWITCH_ALL : SO_SWITCH_NONE;
  443. }
  444.  
  445. void            flagVisibility(Team t, int visible)
  446. {
  447.   if (visible) flagState[int(t)] |= Visible;
  448.   else flagState[int(t)] &= ~Visible;
  449.   flags[int(t)]->whichChild = (flagState[int(t)] == SwitchedOn) ?
  450.                     SO_SWITCH_ALL : SO_SWITCH_NONE;
  451. }
  452.